package com.community.backend.service.impl;

import com.community.backend.service.ChatService;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import lombok.extern.slf4j.Slf4j;
import okhttp3.*;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import java.io.IOException;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.TimeUnit;

@Slf4j
@Service
public class ChatServiceImpl implements ChatService {

    private static final OkHttpClient HTTP_CLIENT = new OkHttpClient().newBuilder()
            .readTimeout(300, TimeUnit.SECONDS)
            .connectTimeout(30, TimeUnit.SECONDS)
            .build();

    // V2 版本接口地址
    private static final String CHAT_URL = "https://qianfan.baidubce.com/v2/chat/completions";

    private final ObjectMapper objectMapper = new ObjectMapper();

    @Value("${baidu.key:}")  // 修正：应该是 baidu.api.key
    private String apiKey;

    @Value("${baidu.qianfan-model:deepseek-v3.1-250821}")
    private String qianfanModel;

    private List<String> availableModels = Arrays.asList(
            "deepseek-v3.1-250821",    // 您有的 DeepSeek 模型
            "ERNIE-Bot-8K",           // 备用模型
            "ERNIE-Bot-turbo-8K",     // 备用模型
            "ERNIE-Speed-8K"          // 备用模型
    );

    /**
     * 检查 API Key 是否有效
     */
    private boolean isApiKeyValid() {
        if (apiKey == null || apiKey.isEmpty()) {
            log.warn("API Key 为 null 或空字符串");
            return false;
        }

        if (apiKey.contains("ALTAK****") || apiKey.contains("您的") || apiKey.contains("example")) {
            log.warn("API Key 包含默认值或示例文本");
            return false;
        }

        if (!apiKey.startsWith("bce-v3/ALTAK")) {
            log.warn("API Key 格式不正确，应以 bce-v3/ALTAK 开头");
            return false;
        }

        if (apiKey.length() < 50) {
            log.warn("API Key 长度过短: {}", apiKey.length());
            return false;
        }

        log.info("API Key 格式验证通过");
        return true;
    }

    @Override
    public void streamChat(String sessionId, String userInput, StreamResponseHandler handler) throws IOException {
        log.info("=== 开始处理用户请求 ===");
        log.info("用户输入: {}", userInput);
        log.info("配置的模型: {}", qianfanModel);
        log.info("API Key 状态: {}", isApiKeyValid() ? "有效" : "无效");

        if (!isApiKeyValid()) {
            useMockResponse(sessionId, userInput, handler);
            return;
        }

        log.info("首先尝试配置的模型: {}", qianfanModel);
        if (tryWithModel(sessionId, userInput, handler, qianfanModel)) {
            return;
        }

        // 如果配置的模型失败，尝试其他模型
        log.info("配置模型失败，尝试其他可用模型");
        for (String model : availableModels) {
            if (!model.equals(qianfanModel)) {
                log.info("尝试模型: {}", model);
                if (tryWithModel(sessionId, userInput, handler, model)) {
                    log.info("成功使用模型: {}", model);
                    return;
                }
            }
        }

        log.error("所有模型尝试均失败");
        useAllModelsFailedResponse(sessionId, userInput, handler);
    }

    private boolean tryWithModel(String sessionId, String userInput, StreamResponseHandler handler, String model) {
        try {
            Map<String, Object> message = new HashMap<>();
            message.put("role", "user");
            message.put("content", userInput);

            Map<String, Object> requestBody = new HashMap<>();
            requestBody.put("messages", new Object[]{message});
            requestBody.put("model", model);
            requestBody.put("stream", false);

            String requestBodyJson = objectMapper.writeValueAsString(requestBody);
            log.info("请求模型: {}, 请求体: {}", model, requestBodyJson);

            MediaType mediaType = MediaType.parse("application/json");
            RequestBody body = RequestBody.create(mediaType, requestBodyJson);

            Request request = new Request.Builder()
                    .url(CHAT_URL)
                    .post(body)
                    .addHeader("Content-Type", "application/json")
                    .addHeader("Authorization", "Bearer " + apiKey)
                    .build();

            try (Response response = HTTP_CLIENT.newCall(request).execute()) {
                log.info("模型 {} 响应状态: {}", model, response.code());

                if (response.isSuccessful() && response.body() != null) {
                    String responseBody = response.body().string();
                    log.info("模型 {} 响应体: {}", model, responseBody);

                    JsonNode jsonResponse = objectMapper.readTree(responseBody);

                    if (!jsonResponse.has("error")) {
                        String content = jsonResponse.get("choices").get(0).get("message").get("content").asText();
                        log.info(" 模型 {} 调用成功!", model);

                        simulateRealisticStreaming(content, handler);
                        return true;
                    } else {
                        String errorMsg = jsonResponse.get("error").get("message").asText();
                        log.warn("模型 {} 返回错误: {}", model, errorMsg);
                    }
                } else {
                    String errorBody = response.body() != null ? response.body().string() : "无响应体";
                    log.warn("模型 {} HTTP 错误: {} - {}", model, response.code(), errorBody);
                }
            }
        } catch (Exception e) {
            log.error("模型 {} 调用异常: {}", model, e.getMessage());
        }
        return false;
    }

    private void useAllModelsFailedResponse(String sessionId, String userInput, StreamResponseHandler handler) {
        String response = "模型调用失败\n\n" +
                "您的提问：「" + userInput + "」\n\n" +
                "检测到您有 DeepSeek-V3.1 模型权限，但调用失败。\n\n" +
                "可能原因：\n" +
                "• 模型名称需要完全匹配\n" +
                "• API Key 权限问题\n" +
                "• 网络连接问题\n\n" +
                "建议检查：\n" +
                "1. 模型名称: deepseek-v3.1-250821\n" +
                "2. API Key 状态\n" +
                "3. 网络连接";

        simulateRealisticStreaming(response, handler);
    }

    /**
     * 模拟响应（降级方案）
     */
    private void useMockResponse(String sessionId, String userInput, StreamResponseHandler handler) {
        String mockResponse = generateMockResponse(userInput);
        simulateRealisticStreaming(mockResponse, handler);
    }

    private String generateMockResponse(String userInput) {
        return "🔧 演示模式\n\n" +
                "您的提问：「" + userInput + "」\n\n" +
                "要使用真实AI功能，请确保：\n" +
                "1. 在 application.yml 中正确配置 baidu.api.key\n" +
                "2. 使用从百度千帆获取的真实 API Key\n" +
                "3. 确保 API Key 有可用额度\n\n" +
                "当前 API Key 状态: " + (isApiKeyValid() ? "有效" : "无效");
    }

    /**
     * 流式输出（保持用户体验）
     */
    private void simulateRealisticStreaming(String content, StreamResponseHandler handler) {
        new Thread(() -> {
            try {
                // 模拟思考延迟
                Thread.sleep(800);
                handler.handle("思考中...");
                Thread.sleep(500);

                // 按字符流式输出
                char[] chars = content.toCharArray();
                StringBuilder currentContent = new StringBuilder();

                for (int i = 0; i < chars.length; i++) {
                    Thread.sleep(30);
                    currentContent.append(chars[i]);
                    handler.handle(currentContent.toString());

                    // 在标点符号后稍微停顿
                    if (chars[i] == '。' || chars[i] == '！' || chars[i] == '？' || chars[i] == '\n') {
                        Thread.sleep(100);
                    }
                }

                // 最终完成
                Thread.sleep(200);
                handler.handle("[DONE]");

            } catch (InterruptedException e) {
                Thread.currentThread().interrupt();
                handler.handle("对话被中断");
            } catch (Exception e) {
                log.error("流式输出异常", e);
                handler.handle("输出异常，请重试");
            }
        }).start();
    }
}